import { createSSRApp } from 'vue'
import { createPinia } from 'pinia'
import './style.css'
import App from './App.vue'
import { MessageType, MessageStatus, MessageUtils } from './utils/messageTypes'
import SponsorBanner from './components/SponsorBanner.vue'
import { NETWORK_CONFIG } from './config/network.js'

// 兼容 Node/H5/小程序端全局对象
declare let global: any;
// setImmediate/clearImmediate 类型声明
declare global {
  var setImmediate: (callback: (...args: any[]) => void, ...args: any[]) => number;
  var clearImmediate: (id: number) => void;
}

// setImmediate polyfill for environments that lack it
if (typeof setImmediate === 'undefined') {
  const globalObj = typeof window !== 'undefined' ? window :
                    typeof globalThis !== 'undefined' ? globalThis :
                    typeof global !== 'undefined' ? global :
                    Function('return this')();
  globalObj.setImmediate = function(fn: (...args: any[]) => void) {
    return setTimeout(fn, 0);
  };
  globalObj.clearImmediate = function(id: number) {
    clearTimeout(id);
  };
}

// 声明全局函数类型
declare global {
  interface Uni {
    handleMarkAsRead: (id: number) => Promise<void>
    handleApprove: (id: number, type: number) => Promise<void>
    handleReject: (id: number, type: number) => Promise<void>
  }
  function getApp(): any
  function getCurrentPages(): any[]
  interface Window {
    __VUE_APP__?: any
    __SPONSOR_BANNER__?: any
    __GLOBAL_DEBUG_BANNER__?: any
    __SIMPLE_BANNER__?: any
    __SPONSOR_MESSAGE__?: any
  }
}

// 定义全局处理函数
const handleMarkAsRead = async (id: number) => {
  try {
    const token = uni.getStorageSync('accessToken');
    const res = await uni.request({
      url: `${NETWORK_CONFIG.API_BASE_URL}/message/read?id=${id}`,
      method: 'POST',
      header: { 'Access-Token': `Bearer ${token}` }
    }) as any;
    
    if (res.statusCode !== 200) {
      throw new Error(res.data?.message || '操作失败');
    }

    uni.showToast({
      title: `消息 ${id} 已标记为已读`,
      icon: 'success',
      duration: 3000
    });
  } catch (error: any) {
    uni.showToast({
      title: error.message || '操作失败',
      icon: 'error',
      duration: 3000
    });
  }
};

const handleApprove = async (id: number, type: number) => {
  try {
    const token = uni.getStorageSync('accessToken');
    let endpoint = '';
    let params = '';
    let actionText = '';
    
    switch (type) {
      case 1:
        endpoint = 'handle-org-apply';
        params = `id=${id}&approve=true&reason=`;
        actionText = '已同意企业入驻申请';
        break;
      case 3:
        endpoint = 'handle-task-apply';
        params = `id=${id}&approve=true&reason=`;
        actionText = '已同意任务申请';
        break;
      case 4:
        endpoint = 'handle-task-completion';
        const proof = await new Promise<string>((resolve) => {
          uni.showModal({
            title: '评价',
            content: '请输入对任务完成的评价：',
            editable: true,
            success: (res) => {
              if (res.confirm && res.content) {
                resolve(res.content);
              } else {
                resolve('');
              }
            }
          });
        });
        if (!proof) return;
        params = `id=${id}&approve=true&proof=${encodeURIComponent(proof)}`;
        actionText = '已同意任务完成';
        break;
    }
    
    const res = await uni.request({
      url: `${NETWORK_CONFIG.API_BASE_URL}/message/${endpoint}?${params}`,
      method: 'POST',
      header: { 'Access-Token': `Bearer ${token}` }
    }) as any;

    if (res.statusCode !== 200) {
      throw new Error(res.data?.message || '操作失败');
    }

    uni.showToast({
      title: actionText,
      icon: 'success',
      duration: 3000
    });
  } catch (error: any) {
    uni.showToast({
      title: error.message || '操作失败',
      icon: 'error',
      duration: 3000
    });
  }
};

const handleReject = async (id: number, type: number) => {
  try {
    const token = uni.getStorageSync('accessToken');
    let endpoint = '';
    let params = '';
    let actionText = '';
    
    switch (type) {
      case 1:
        endpoint = 'handle-org-apply';
        const reason1 = await new Promise<string>((resolve) => {
          uni.showModal({
            title: '拒绝理由',
            content: '请输入拒绝理由：',
            editable: true,
            success: (res) => {
              if (res.confirm && res.content) {
                resolve(res.content);
              } else {
                resolve('');
              }
            }
          });
        });
        if (!reason1) return;
        params = `id=${id}&approve=false&reason=${encodeURIComponent(reason1)}`;
        actionText = '已拒绝企业入驻申请';
        break;
      case 3:
        endpoint = 'handle-task-apply';
        const reason2 = await new Promise<string>((resolve) => {
          uni.showModal({
            title: '拒绝理由',
            content: '请输入拒绝理由：',
            editable: true,
            success: (res) => {
              if (res.confirm && res.content) {
                resolve(res.content);
              } else {
                resolve('');
              }
            }
          });
        });
        if (!reason2) return;
        params = `id=${id}&approve=false&reason=${encodeURIComponent(reason2)}`;
        actionText = '已拒绝任务申请';
        break;
      case 4:
        endpoint = 'handle-task-completion';
        const reason3 = await new Promise<string>((resolve) => {
          uni.showModal({
            title: '拒绝理由',
            content: '请输入拒绝理由：',
            editable: true,
            success: (res) => {
              if (res.confirm && res.content) {
                resolve(res.content);
              } else {
                resolve('');
              }
            }
          });
        });
        if (!reason3) return;
        params = `id=${id}&approve=false&proof=${encodeURIComponent(reason3)}`;
        actionText = '已拒绝任务完成';
        break;
    }
    
    const res = await uni.request({
      url: `${NETWORK_CONFIG.API_BASE_URL}/message/${endpoint}?${params}`,
      method: 'POST',
      header: { 'Access-Token': `Bearer ${token}` }
    }) as any;

    if (res.statusCode !== 200) {
      throw new Error(res.data?.message || '操作失败');
    }

    uni.showToast({
      title: actionText,
      icon: 'success',
      duration: 3000
    });
  } catch (error: any) {
    uni.showToast({
      title: error.message || '操作失败',
      icon: 'error',
      duration: 3000
    });
  }
};

// 刷新任务相关页面的函数
const refreshTaskRelatedPages = () => {
  console.log('🔄 刷新任务相关页面')
  
  // 发送全局事件通知所有页面刷新
  uni.$emit('task-related-update', {
    timestamp: Date.now(),
    message: '任务相关数据已更新'
  })
  
  // 如果当前在任务详情页面，直接刷新
  const pages = getCurrentPages()
  if (pages.length > 0) {
    const currentPage = pages[pages.length - 1]
    const route = currentPage.route
    
    if (route === 'task/detail') {
      // 任务详情页面
      if (currentPage.$vm && currentPage.$vm.fetchTaskDetail) {
        currentPage.$vm.fetchTaskDetail()
      }
      if (currentPage.$vm && currentPage.$vm.checkUserApplied) {
        currentPage.$vm.checkUserApplied()
      }
      if (currentPage.$vm && currentPage.$vm.checkPendingMessages) {
        currentPage.$vm.checkPendingMessages()
      }
    } else if (route === 'pages/message/index') {
      // 消息中心页面
      if (currentPage.$vm && currentPage.$vm.fetchMessages) {
        currentPage.$vm.fetchMessages()
      }
    } else if (route === 'pages/index/index') {
      // 首页
      if (currentPage.$vm && currentPage.$vm.loadTasks) {
        currentPage.$vm.loadTasks()
      }
    }
  }
}

// 将处理函数挂载到全局
(uni as any).handleMarkAsRead = handleMarkAsRead;
(uni as any).handleApprove = handleApprove;
(uni as any).handleReject = handleReject;
(uni as any).refreshTaskRelatedPages = refreshTaskRelatedPages;

// 初始化 WebSocket（UniApp 原生 SocketTask 实现）
const connectWebSocket = () => {
  const token = uni.getStorageSync('accessToken')
  if (!token) {
    console.log('未找到 token，暂不建立 WebSocket 连接')
    return null
  }

  console.log('开始建立 WebSocket 连接...')
  let retryCount = 0
  const maxRetries = 5
  const retryDelay = 5000
  let socketTask: any | null = null
  let isConnecting = false

  const typeText = (t: number) => {
    return MessageUtils.getTypeDescription(t);
  };

  const statusText = (s: number) => {
    return MessageUtils.getStatusDescription(s);
  };

  const formatTime = (t: string) => {
    return MessageUtils.formatTime(t);
  };

  const tryConnect = () => {
    console.log('🔍 尝试建立WebSocket连接...')
    console.log('🔍 当前重试次数:', retryCount)
    console.log('🔍 最大重试次数:', maxRetries)
    console.log('🔍 是否正在连接:', isConnecting)
    
    if (isConnecting) {
      console.log('🔍 正在连接中，跳过')
      return null
    }
    if (retryCount >= maxRetries) {
      console.error('🔍 WebSocket 连接重试次数已达上限')
      return null
    }
    isConnecting = true

    console.log('🔍 开始创建WebSocket连接...')
    console.log('🔍 连接URL:', `${NETWORK_CONFIG.WS_URL}/ws?token=${token}`)
    
    socketTask = uni.connectSocket({
      url: `${NETWORK_CONFIG.WS_URL}/ws?token=${token}`,
      success: () => {
        console.log('🔍 WebSocket 连接请求已发送')
      },
      fail: (error) => {
        console.error('🔍 WebSocket 连接请求失败:', error)
        isConnecting = false
        retryCount++
        console.log(`🔍 将在 ${retryDelay/1000} 秒后进行第 ${retryCount} 次重试`)
        setTimeout(tryConnect, retryDelay)
      }
    })

    if (!socketTask) {
      isConnecting = false
      return null
    }

    socketTask.onOpen(() => {
      console.log('🔍 WebSocket 连接已打开')
      console.log('🔍 WebSocket readyState:', (socketTask as any).readyState)
      retryCount = 0
      isConnecting = false
    })

    socketTask.onMessage((res: any) => {
      try {
        console.log('🔍 WebSocket原始消息:', res.data)
        console.log('🔍 消息类型:', typeof res.data)
        console.log('🔍 消息长度:', res.data?.length)
        console.log('🔍 消息内容预览:', res.data?.substring(0, 100))
        
        const message = JSON.parse(res.data)
        console.log('🔍 解析后的消息:', message)
        console.log('🔍 消息类型检查:', message.type)
        console.log('🔍 消息ID:', message.id)
        
        // 消息去重：检查是否已经处理过相同的消息
        if (message.id) {
          const messageKey = `processed_${message.id}`
          if (uni.getStorageSync(messageKey)) {
            console.log('消息已处理过，跳过:', message.id)
            return
          }
          // 标记消息为已处理
          uni.setStorageSync(messageKey, true)
          // 5分钟后清理标记
          setTimeout(() => {
            uni.removeStorageSync(messageKey)
          }, 5 * 60 * 1000)
        }

        if (message.type === 'task-progress') {
          console.log('收到任务进度更新:', message)
          uni.$emit('task-progress-update', message)
          return
        }

        // 处理聊天消息（type为chatmessage）
        if (message.type === 'chatmessage' && message.message) {
          console.log('收到聊天消息:', message)
          uni.$emit('chatMessage', message)
          return
        }

        // 处理通知消息（type为message，有id、title等字段）
        if (message.type === 'message' && (message.id || message.title)) {
          console.log('收到通知消息:', message)
          // 通知消息会在下面的逻辑中处理
        }

        if (message.type === 'message_sent') {
          console.log('收到消息发送确认:', message)
          uni.$emit('messageSent', message)
          return
        }

        if (message.type === 'error') {
          console.log('收到错误消息:', message)
          uni.$emit('websocketError', message)
          return
        }

        // 处理团队成员加入消息
        if (message.type === 'team_member_joined') {
          console.log('收到团队成员加入消息:', message)
          uni.$emit('team-member-joined', message)
          return
        }

        // 处理团队成员退出消息
        if (message.type === 'team_member_left') {
          console.log('收到团队成员退出消息:', message)
          uni.$emit('team-member-left', message)
          return
        }

        // 处理团队成员被移除消息
        if (message.type === 'team_member_removed') {
          console.log('收到团队成员被移除消息:', message)
          uni.$emit('team-member-removed', message)
          return
        }

        // 处理团队投票发起消息
        if (message.type === 'team_vote_initiated') {
          console.log('收到团队投票发起消息:', message)
          uni.$emit('team-vote-initiated', message)
          return
        }

        // 处理团队投票结果消息
        if (message.type === 'team_vote_result') {
          console.log('收到团队投票结果消息:', message)
          uni.$emit('team-vote-result', message)
          return
        }

        if (message.type === 'sponsor_success') {
          console.log('🎉 收到赞助成功消息:', message)
          console.log('🎉 message.level 值:', message.level, '类型:', typeof message.level)
          console.log('🎉 message.level 是否为空:', message.level === '', '是否为null:', message.level === null, '是否为undefined:', message.level === undefined)
          
          // 使用和普通消息通知一样的方式：直接显示
          const sponsorText = `${message.sponsorName} 赞助了 ¥${message.amount} (${message.sponsorType})`
          const levelText = (message.level && message.level !== '' && message.level !== null && message.level !== undefined) ? ` - 等级${message.level}` : ''
          
          console.log('🎉 准备显示Toast:', sponsorText + levelText)
          console.log('🎉 Toast标题长度:', (sponsorText + levelText).length)
          
          // 显示赞助成功提示 - 使用uni.showToast，简单可靠
          console.log('🎉 开始显示Toast...')
          
          // 根据赞助金额显示不同样式的Toast
          let toastTitle = sponsorText + levelText
          let toastIcon: 'success' | 'none' | 'loading' | 'error' = 'success'
          let toastDuration = 3000
          
          // 根据金额调整显示效果
          if (message.amount >= 1000) {
            toastTitle = `🎉 ${toastTitle} 🎉`
            toastDuration = 5000
          } else if (message.amount >= 100) {
            toastTitle = `✨ ${toastTitle} ✨`
            toastDuration = 4000
          }
          
          // 三重播报：Toast + 炫酷横幅 + 原生通知
          console.log('🎉 使用三重播报显示赞助信息')
          
          // 方式1：Toast播报（轻量级）
          uni.showToast({
            title: toastTitle,
            icon: toastIcon,
            duration: toastDuration
          })
          
          // 方式2：炫酷横幅播报（视觉效果）
          try {
            const app = getApp()
            if (app && app.__SPONSOR_BANNER__) {
              console.log('🎉 使用炫酷横幅显示')
              app.__SPONSOR_BANNER__.showSponsorBanner(
                message.amount,
                message.sponsorName,
                message.sponsorType,
                message.level || 0,
                message.avatarUrl || '',
                message.duration || 5000
              )
            } else {
              console.log('🎉 炫酷横幅未找到')
            }
          } catch (error) {
            console.log('🎉 获取炫酷横幅失败:', error)
          }
          
          // 方式3：原生通知播报（详细信息）
          try {
            const app = getApp()
            if (app && app.__NATIVE_NOTIFICATION__) {
              console.log('🎉 使用原生通知显示')
              if (message.level >= 4) {
                // 高等级使用组合通知
                app.__NATIVE_NOTIFICATION__.showCombo(message)
              } else if (message.level >= 2) {
                // 中等级使用Modal + Loading
                app.__NATIVE_NOTIFICATION__.show(message)
                setTimeout(() => {
                  app.__NATIVE_NOTIFICATION__.showLoading(message)
                }, 1000)
              } else {
                // 低等级使用简单Modal
                app.__NATIVE_NOTIFICATION__.show(message)
              }
            } else {
              console.log('🎉 原生通知未找到')
            }
          } catch (error) {
            console.log('🎉 获取原生通知失败:', error)
          }
          
          console.log('🎉 三重播报已显示:', toastTitle)
          
          // 同时发送事件给组件（如果组件存在的话）
          uni.$emit('sponsor-success', message)
          
          return
        }

        // 检查是否是任务相关的申请消息
        const isTaskApplication = (message.type === 1 || message.type === 3 || message.type === 4 || message.type === 9) && message.status === 0
        
        if (isTaskApplication) {
          // 任务申请类消息：显示同意/拒绝/暂不处理弹窗
          uni.showModal({
            title: message.title || '新消息',
            content: `\n标题：${message.title || '无'}\n内容：${message.content || '无'}\n类型：${typeText(message.type)}\n状态：${statusText(message.status)}\n时间：${formatTime(message.createTime)}\n          `,
            showCancel: true,
            confirmText: '同意',
            cancelText: '拒绝',
            success: (res) => {
              if (res.confirm) {
                handleApprove(message.id, message.type)
              } else if (res.cancel) {
                handleReject(message.id, message.type)
              }
              // 无论选择什么，都刷新相关页面
              refreshTaskRelatedPages()
            }
          })
        } else {
          // 其他消息：显示简单的确认弹窗
          uni.showModal({
            title: message.title || '新消息',
            content: `\n标题：${message.title || '无'}\n内容：${message.content || '无'}\n类型：${typeText(message.type)}\n状态：${statusText(message.status)}\n时间：${formatTime(message.createTime)}\n          `,
            showCancel: false,
            confirmText: message.status === 0 ? '标记已读' : '确定',
            success: (res) => {
              if (res.confirm) {
                if (message.status === 0) {
                  handleMarkAsRead(message.id)
                }
              }
              // 刷新相关页面
              refreshTaskRelatedPages()
            }
          })
        }
      } catch (error) {
        console.error('处理 WebSocket 消息失败:', error)
      }
    })

    socketTask.onError((error: any) => {
      console.error('🔍 WebSocket 发生错误:', error)
      console.error('🔍 WebSocket readyState:', (socketTask as any).readyState)
      isConnecting = false
      retryCount++
      if (retryCount < maxRetries) {
        console.log(`将在 ${retryDelay/1000} 秒后进行第 ${retryCount} 次重试`)
        setTimeout(tryConnect, retryDelay)
      } else {
        console.error('WebSocket 连接失败次数过多，停止重试')
      }
    })

    socketTask.onClose(() => {
      console.log('🔍 WebSocket 连接已关闭')
      console.log('🔍 WebSocket readyState:', (socketTask as any).readyState)
      isConnecting = false
      if (retryCount < maxRetries) {
        retryCount++
        console.log(`将在 ${retryDelay/1000} 秒后进行第 ${retryCount} 次重试`)
        setTimeout(tryConnect, retryDelay)
      }
    })

    return socketTask
  }

  // 监听发送WebSocket消息事件
  ;(uni as any).$on('sendWebSocketMessage', (message: any) => {
    console.log('🔍 收到发送消息请求:', message)
    console.log('🔍 WebSocket状态:', (socketTask as any)?.readyState)
    if (socketTask && (socketTask as any).readyState === 1) {
      console.log('🔍 通过全局WebSocket发送消息:', message)
      ;(socketTask as any).send({
        data: JSON.stringify(message)
      })
    } else {
      console.error('🔍 全局WebSocket未连接，无法发送消息')
      console.error('🔍 socketTask:', socketTask)
      console.error('🔍 readyState:', (socketTask as any)?.readyState)
    }
  })

  return tryConnect()
}

// 辅助函数
const typeText = (t: number) => {
  switch (t) {
    case 1: return '任务申请';
    case 2: return '任务进度';
    case 3: return '任务申请';
    case 4: return '任务完成';
    case 5: return '评价';
    default: return t as any;
  }
};

const statusText = (s: number) => {
  switch (s) {
    case 0: return '未读';
    case 1: return '已读';
    case 2: return '已同意';
    case 3: return '已拒绝';
    default: return s as any;
  }
};

const formatTime = (t: string) => {
  if (!t) return '-';
  return t.replace('T', ' ').slice(0, 19);
};


export function createApp() {
  console.log('开始创建应用...')
  
  const app = createSSRApp(App)
  
  // 先创建 Pinia 实例
  const pinia = createPinia()
  console.log('🎉 Pinia 实例已创建')
  
  // 使用 Pinia
  app.use(pinia)
  console.log('🎉 Pinia 已注册到应用')
  
  // 注册全局组件
  app.component('SponsorBanner', SponsorBanner)
  console.log('🎉 已注册SponsorBanner组件')
  
  // 设置全局请求拦截器（使用类型断言避免TypeScript错误）
  ;(uni as any).addInterceptor?.('request', {
    invoke(args: any) {
      // 确保 header 对象存在
      if (!args.header) {
        args.header = {};
      }
      
      // 自动添加 Access-Token 请求头
      const token = uni.getStorageSync('accessToken');
      if (token && !args.header['Access-Token'] && !args.header['access-token']) {
        args.header['Access-Token'] = `Bearer ${token}`;
      }
    }
  });
  console.log('🎉 已设置全局请求拦截器')
  
  // 初始化 WebSocket 客户端
  const websocket = connectWebSocket()
  if (websocket) {
    ;(app as any).config.globalProperties.$websocket = websocket
  }

  return {
    app,
    pinia
  }
}

// 导出 pinia 实例（从 createApp 函数中获取）
// export const pinia = createPinia()

// 将 connectWebSocket 函数暴露到全局，供登录页面调用
;(uni as any).connectWebSocket = connectWebSocket